libobs_source_macro/
fields.rs1use proc_macro2::TokenStream;
2use quote::quote;
3use syn::{punctuated::Punctuated, token::Comma, Field};
4
5pub fn generate_struct_fields(fields: &Punctuated<Field, Comma>) -> (Vec<TokenStream>, Vec<TokenStream>) {
6 let maybe_obs_properties = fields
7 .iter()
8 .map(|f| {
9 let attr = f.attrs.iter().find(|e| e.path().is_ident("obs_property"));
10
11 (f, attr)
12 })
13 .collect::<Vec<_>>();
14
15 let obs_properties = maybe_obs_properties
16 .iter()
17 .filter_map(|(f, attr)| if attr.is_some() { Some(f) } else { None })
18 .collect::<Vec<_>>();
19
20 let non_obs_properties = maybe_obs_properties
21 .iter()
22 .filter_map(|(f, attr)| if let Some(_a) = attr { None } else { Some(f) })
23 .collect::<Vec<_>>();
24
25 let mut struct_fields = Vec::<TokenStream>::new();
26 let mut struct_initializers = Vec::<TokenStream>::new();
27
28 for field in obs_properties {
29 let name = &field.ident;
30 struct_fields.push(quote! {
31 #name: u8
33 });
34
35 struct_initializers.push(quote! {
36 #name: 0
37 });
38 }
39
40 for ele in non_obs_properties {
41 let name = &ele.ident;
42 #[allow(dead_code)]
43 let field_type = &ele.ty;
44 struct_fields.push(quote! {
45 #name: #field_type
46 });
47
48 struct_initializers.push(quote! {
49 #name: Default::default()
50 });
51 }
52
53 (struct_fields, struct_initializers)
54}